cmake_minimum_required(VERSION 3.10)

if (NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release)
endif()
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

project(opengltutor
    LANGUAGES CXX C
    DESCRIPTION "An indispensable online webinar open course for computer graphics beginners to learn every bit of modern OpenGL and build a popular 3D game engine."
    HOMEPAGE_URL https://github.com/parallel101/opengltutor
    )

if (PROJECT_BINARY_DIR STREQUAL PROJECT_SOURCE_DIR)
    message(FATAL_ERROR "The binary directory of CMake cannot be the same as source directory! "
        "Do not use 'cmake .'! Please consider use 'cmake -B build' to specify a different binary directory. "
        "Otherwise this project may fail to build, or make Git hard to exclude binary files. "
        "For Windows, it is highly recommended to use Visual Studio as IDE for CMake projects.")
endif()

if (NOT MSVC)
    find_program(CCACHE_PROGRAM ccache)  # Compilation speed up: https://ccache.dev
    if (CCACHE_PROGRAM)
        message(STATUS "Found CCache: ${CCACHE_PROGRAM}")
        set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PROGRAM})
        set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE_PROGRAM})
    endif()
endif()

if (MSVC)  # 1. fix string literial cannot include unicode characters; 2. rid min and max macros; 3. get back M_PI, M_E macros
    add_compile_options($<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/utf-8$<SEMICOLON>/DNOMINMAX$<SEMICOLON>/D_USE_MATH_DEFINES>)
    add_compile_options($<$<COMPILE_LANG_AND_ID:C,MSVC>:/utf-8$<SEMICOLON>/DNOMINMAX$<SEMICOLON>/D_USE_MATH_DEFINES>)
endif()
# KISS FFT
set(KISS_SRC "3rdparty/kissfft/kiss_fft.h" 
             "3rdparty/kissfft/kiss_fftr.h" 
             "3rdparty/kissfft/kiss_fft.c" 
             "3rdparty/kissfft/kiss_fftr.c")

# EVERYTHING ELSE
include_directories("3rdparty" "3rdparty/kissfft" "include")

add_library(tutor 
src/ASCIIFontData.cpp
src/check_gl.cpp
src/Game.cpp
src/Image.cpp
src/InputCtl.cpp
src/OBJ.cpp
)
target_include_directories(tutor PUBLIC include)
target_compile_features(tutor PRIVATE cxx_std_17)
target_link_libraries(tutor glad glm glfw)

# file(GLOB_RECURSE sources CONFIGURE_DEPENDS src/*.cpp  implot/*.cpp common/*.cpp 3rdparty/kissfft/*.c)
# file(GLOB_RECURSE headers CONFIGURE_DEPENDS include/*.h include/*.hpp  implot/*.h common/*.h common/*.hpp 3rdparty/*.h 3rdparty/*.hpp)
add_executable(${PROJECT_NAME} "src/main.cpp")

# target_link_libraries(${PROJECT_NAME} PUBLIC imgui implot)
target_include_directories(${PROJECT_NAME} PUBLIC include)

# file(GLOB_RECURSE sources CONFIGURE_DEPENDS src/*.cpp src/*.c)
# file(GLOB_RECURSE headers CONFIGURE_DEPENDS include/*.h include/*.hpp)
# add_executable(${PROJECT_NAME} ${sources} ${headers})
# target_include_directories(${PROJECT_NAME} PUBLIC include)

add_subdirectory(glm)
target_link_libraries(${PROJECT_NAME} PUBLIC glm)
add_subdirectory(glfw)
# target_link_libraries(${PROJECT_NAME} PUBLIC glfw)
add_subdirectory(glad)
# target_link_libraries(${PROJECT_NAME} PUBLIC glad)
add_subdirectory(imgui)
# target_link_libraries(${PROJECT_NAME} PUBLIC imgui)
add_subdirectory(colorte)
add_subdirectory(implot)
target_link_libraries(${PROJECT_NAME} PUBLIC implot colorte)

add_subdirectory(common)
add_subdirectory(iir1)
add_subdirectory(ImCoolBar)
set_target_properties(ImCoolbar PROPERTIES FOLDER Lib)
target_include_directories(ImCoolbar PRIVATE
	imgui/src
)

add_subdirectory(imknobs)
set_target_properties(imknobs PROPERTIES FOLDER Lib)
target_include_directories(imknobs PRIVATE
	imgui/src
)

target_compile_definitions(${PROJECT_NAME} PUBLIC -DOPENGLTUTOR_HOME=\"${CMAKE_CURRENT_SOURCE_DIR}/\")

add_executable(implotDemo WIN32 "src/implotDemo.cpp")
target_include_directories(implotDemo PRIVATE common/src)
target_link_libraries(implotDemo app)

add_executable(imguiDemo "src/imguiDemo.cpp")
target_include_directories(imguiDemo PRIVATE common/src)
target_link_libraries(imguiDemo app)

add_executable(imfilebrowser "src/imfilebrowser.cpp")
target_include_directories(imfilebrowser PRIVATE common/src)
target_link_libraries(imfilebrowser app)

add_executable(imcoolBar "src/imcoolBar.cpp")
target_include_directories(imcoolBar PRIVATE ImCoolBar)
target_link_libraries(imcoolBar app ${IMCOOLBAR_LIBRARIES})

add_executable(imknobsDemo "src/imknobs.cpp")
target_include_directories(imknobsDemo  PRIVATE imknobs)
target_link_libraries(imknobsDemo app ${IMKNOBS_LIBRARIES})
# 在windows平台无法编译成功
if(CMAKE_HOST_UNIX)
# graph demo
add_executable(graph "src/graph.cpp")
target_link_libraries(graph app)
target_include_directories(graph PRIVATE "3rdparty")
if (MSVC)
  set_target_properties(graph PROPERTIES COMPILE_FLAGS "/bigobj")
endif()
target_compile_features(graph PRIVATE cxx_std_20)

add_executable(graphSquareWave "src/graphSquareWave.cpp")
target_link_libraries(graphSquareWave app)
target_include_directories(graphSquareWave PRIVATE "3rdparty")
if (MSVC)
  set_target_properties(graphSquareWave PROPERTIES COMPILE_FLAGS "/bigobj")
endif()
target_compile_features(graphSquareWave PRIVATE cxx_std_20)

endif()

# perlin demo
add_executable(perlin "src/perlin.cpp")
target_link_libraries(perlin app)
target_include_directories(perlin PRIVATE "3rdparty")

# mandel demo
# add_executable(mandel "src/mandel.cpp")
# target_link_libraries(mandel app)
# target_include_directories(mandel PRIVATE "3rdparty")
# if (MSVC)
#   target_compile_options(mandel PRIVATE /arch:AVX2 /fp:fast /openmp)
# endif()

# filter demo
add_executable(filter "src/filter.cpp" ${KISS_SRC})
target_link_libraries(filter app iir::iir_static)
target_compile_features(filter PRIVATE cxx_std_17)
target_compile_definitions(filter PRIVATE kiss_fft_scalar=double NOMINMAX)

# spectrogram demo
# add_executable(spectrogram "src/spectrogram.cpp" ${KISS_SRC})              
# target_link_libraries(spectrogram app)        
# target_compile_features(spectrogram PRIVATE cxx_std_17)
# add_custom_command(TARGET spectrogram POST_BUILD  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/resources/audio/aphex_twin_formula.wav $<TARGET_FILE_DIR:spectrogram>)

# voice demo
add_executable(voice "src/voice.cpp" ${KISS_SRC})              
target_link_libraries(voice app)        
target_compile_features(voice PRIVATE cxx_std_17)